package com.orangecy.rulesubscribe.config;

import com.google.common.collect.Lists;
import com.orangecy.common.enums.StatusEnum;
import com.orangecy.common.exception.OrangeCyException;
import com.orangecy.rulesubscribe.define.SubscribeRuleDTO;
import com.orangecy.rulesubscribe.define.SubscriberDefineDTO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author : orangeCy.奕
 * @Product : 猎豹养成产品源码
 * @Time : 2021/10/22
 * @Desc : 订阅者池配置
 * <p>
 *     {
 *         "subscriber_code":"code",
 *         "subscriber_name":"name",
 *         "subscriber_type":"type",
 *         "description":"desc",
 *         "status":1,
 *         "rules":[
 *              {
 *                  "rule_code":"1",
 *                  "rule_priority":1,
 *                  "subscribe_condition":"",
 *                  "subscribe_status":1,
 *                  "invalid_start_time":"2021-11-07",
 *                  "invalid_end_time":"2021-11-08"
 *
 *              }
 *         ]
 *     }
 * </p>
 */
public class SubscriberDefinePoolConfig {

    private static List<SubscriberDefineDTO> initSubscriberDefinePool() {
        List<SubscriberDefineDTO> subscriberDefinePool = Lists.newArrayList();
        SubscriberDefineDTO subscriberDefineDTO = new SubscriberDefineDTO();
        subscriberDefinePool.add(subscriberDefineDTO);
        return subscriberDefinePool;
    }

    /**
     * 根据订阅者code查询订阅者
     * @param subscribeCode
     * @return
     */
    public static SubscriberDefineDTO findSubscriberByCode(String subscribeCode) {
        List<SubscriberDefineDTO> subscriberDefineDTOS = initSubscriberDefinePool();
        if(CollectionUtils.isEmpty(subscriberDefineDTOS) || StringUtils.isBlank(subscribeCode)) {
            throw new OrangeCyException("param is null");
        }
        List<SubscriberDefineDTO> effectSubscriberList = subscriberDefineDTOS.stream().filter(e -> Objects.equals(e.getSubscriberCode(), subscribeCode))
                .filter(e -> StatusEnum.EFFECT.getCode().equals(e.getStatus()))
                .collect(Collectors.toList());
        if(CollectionUtils.isEmpty(effectSubscriberList)) {
            //如果说此code不存在生效的
            throw new OrangeCyException("subscribeCode is not effect");
        }
        if(effectSubscriberList.size() > 1) {
            throw new OrangeCyException("subscribeCode over limit 1");
        }
        return effectSubscriberList.get(0);
    }

    /**
     * 从订阅中获取match条件的集合规则
     * @param subscriberDefineDTO
     * @return
     */
    public static List<SubscribeRuleDTO> mappingSubscribeRules(SubscriberDefineDTO subscriberDefineDTO){
        if(Objects.isNull(subscriberDefineDTO)) {
            throw new OrangeCyException("subscriberDefineDTO is null");
        }
        List<SubscribeRuleDTO> rules = subscriberDefineDTO.getRules();
        if(CollectionUtils.isEmpty(rules)) {
            //如果没配置 返回空集合
            return Collections.emptyList();
        }
        return rules.stream()
                //找到生效的
                .filter(e -> StatusEnum.EFFECT.getCode().equals(e.getSubscriberStatus()))
                //找到符合条件的
                .filter(e -> subscribeCondition(e, subscriberDefineDTO))
                //过滤时效配置
                .filter(SubscriberDefinePoolConfig::matchSubscribePeriod)
                //配置排序顺序 注意这里防止npe 重复priority
                .sorted(Comparator.comparing(SubscribeRuleDTO::getRulePriority, Comparator.nullsLast(Integer::compare)))
                .collect(Collectors.toList());
    }

    private static boolean subscribeCondition(SubscribeRuleDTO ruleDTO, SubscriberDefineDTO defineDTO) {
        // temp mock
        return true;
    }

    private static boolean matchSubscribePeriod(SubscribeRuleDTO ruleDTO) {
        //temp mock todo
        return true;
    }
}